#version 330 core
in vec4 vertexColor;
in vec2 texCoord;

out vec4 FragColor;
//uniform vec4 outColor;
uniform sampler2D ourTexcoord;
uniform sampler2D ourTexcoord_2;

uniform vec3 objColor;
uniform vec3 ambientColor;
uniform vec3 lightPos;
uniform vec3 lightUniform;
//uniform vec3 lightDir;
uniform vec3 lightColor;
uniform vec3 cameraPos;

in vec3 modelPos;
in vec3 Normal;
in vec2 UV;

struct LightDiractional{
	vec3 pos;
	vec3 color;
	vec3 dirToLight;
};

struct LightSpot{
	
	vec3 pos;
	vec3 color;
	vec3 dirToLight;
	float constant;
	float linear;
	float quadratic;
	float cosInThy;
	float cosOutThy;
};

struct LightPoint{
	vec3 pos;
	vec3 color;
	vec3 dirToLight;
	float constant;
	float linear;
	float quadratic;
};

struct Material{
	vec3 ambient;
	sampler2D emission;
	vec3 emissionColor;
	vec3 diffuseColor;
	sampler2D diffuse;
	vec3 specularColor;
	sampler2D specular;
	float shiness;
};
uniform LightPoint lightPoint1;
uniform LightSpot lightSpot;
uniform LightDiractional lightDiractional;

uniform Material material;

vec3 CalLightDirectional(LightDiractional light, vec3 uNormal, vec3 viewDir){
	
	float diffuseIntensity = max(dot(light.dirToLight, uNormal), 0);
	vec3 diffuseColor = light.color * diffuseIntensity * texture(material.diffuse, UV).rgb;
	
	vec3 r = reflect(-light.dirToLight, uNormal);
	float specularIntensity = pow(max(dot(r, viewDir), 0), material.shiness);
	vec3 specularColor = light.color * specularIntensity * texture(material.specular, UV).rgb * material.specularColor;
	
	vec3 result = diffuseColor + specularColor;
	return result;
}

vec3 CalLightPoint(LightPoint light, vec3 uNormal, vec3 viewDir){
	float dis = length(light.pos - modelPos);
	float attenuantion = 1/(light.constant + light.linear * dis + light.quadratic * (dis * dis));
	
	float diffuseIntensity = max(dot(normalize(light.pos - modelPos), uNormal), 0) * attenuantion;
	vec3 diffuseColor = light.color * diffuseIntensity * texture(material.diffuse, UV).rgb;
	
	vec3 r = reflect(-normalize((light.pos - modelPos)), uNormal);
	float specularIntensity = pow(max(dot(r, viewDir), 0), material.shiness) * attenuantion;
	vec3 specularColor = light.color * specularIntensity * texture(material.specular, UV).rgb;
	
	vec3 result = diffuseColor + specularColor;
	return result;
}

vec3 CalLightSpot(LightSpot light, vec3 uNormal, vec3 viewDir){
	
	float dis = length(light.pos - modelPos);
	float attenuantion = 1/(light.constant + light.linear * dis + light.quadratic * (dis * dis));
	
	float spotRatio = 0;
	float cosTheta = dot(normalize(modelPos - light.pos), -1 * light.dirToLight);
	if (cosTheta > light.cosInThy){
		spotRatio=1.0;
	}
	else if (cosTheta > light.cosOutThy) {
		spotRatio = (cosTheta - light.cosOutThy)/(light.cosInThy - light.cosOutThy);
	} else {
		spotRatio=0;
	}
	float diffuseIntensity = max(dot(normalize(light.pos - modelPos), uNormal), 0) * attenuantion;
	vec3 diffuseColor = light.color * diffuseIntensity * texture(material.diffuse, UV).rgb;
	
	vec3 r = reflect(-normalize((light.pos - modelPos)), uNormal);
	float specularIntensity = pow(max(dot(r, viewDir), 0), material.shiness) * attenuantion;
	vec3 specularColor = light.color * specularIntensity * texture(material.specular, UV).rgb;
	
	vec3 result = (diffuseColor + specularColor) * spotRatio;
	
	return result;
}
void main() {
	
	vec3 result=vec3(0, 0, 0);
	vec3 uNormal = normalize(Normal);
	vec3 viewDir = normalize(cameraPos - modelPos);
	
	result += CalLightDirectional(lightDiractional, uNormal, viewDir);
	
	//   result += CalLightPoint(lightPoint1, uNormal, viewDir);
	//
	//   result += CalLightSpot(lightSpot, uNormal, viewDir);
	
	FragColor =vec4(result, 1.0);
}